home *** CD-ROM | disk | FTP | other *** search
- package de.trantor.mail;
-
- import java.io.ByteArrayOutputStream;
- import java.util.Vector;
-
- public class MimeDecoder {
- private Vector lines;
- private int begin;
- private int end;
- private String type;
- private String name;
- private String encoding;
- private Vector parts;
-
- public MimeDecoder(Message message) {
- this.init(message.getLines(), 0, message.getLines().size());
- }
-
- private MimeDecoder(MimeDecoder parent, int begin, int end) {
- this.init(parent.lines, begin, end);
- }
-
- private void init(Vector lines, int begin, int end) {
- this.lines = lines;
- String s = (String)lines.elementAt(begin);
-
- while(!s.equals("")) {
- ++begin;
-
- while(begin < end) {
- String t = (String)lines.elementAt(begin);
- if (!t.startsWith(" ") && !t.startsWith("\t")) {
- break;
- }
-
- s = s + t;
- ++begin;
- }
-
- String name = Message.getStringName(s).toLowerCase();
- if (!name.equals("content-type")) {
- if (name.equals("content-transfer-encoding")) {
- this.encoding = Message.getStringValue(s);
- }
- } else {
- String[] elements = Message.getStringElements(Message.getStringValue(s));
- this.type = elements[0];
-
- for(int i = 1; i < elements.length; ++i) {
- if (this.type.startsWith("multipart/") && getStringName(elements[i]).equals("boundary")) {
- String boundary = "--" + getStringValue(elements[i]);
- this.parts = new Vector();
-
- for(int j = begin; j < end; ++j) {
- if (this.getLine(j).startsWith(boundary)) {
- this.parts.addElement(new Integer(j));
- }
- }
- } else if (getStringName(elements[i]).equals("name")) {
- this.name = getStringValue(elements[i]);
- }
- }
- }
-
- if (begin < end) {
- s = (String)lines.elementAt(begin);
- } else {
- s = "";
- }
- }
-
- this.begin = begin;
- this.end = end;
- }
-
- private String getLine(int index) {
- return (String)this.lines.elementAt(index);
- }
-
- public int getBodyLineCount() {
- return this.end - this.begin;
- }
-
- public String getBodyLine(int index) throws ArrayIndexOutOfBoundsException {
- if (index >= 0 && index < this.end - this.begin) {
- return (String)this.lines.elementAt(this.begin + index);
- } else {
- throw new ArrayIndexOutOfBoundsException(index);
- }
- }
-
- public byte[] getBodyBytes() {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
- for(int i = 0; i < this.getBodyLineCount(); ++i) {
- decode(this.getBodyLine(i), bos);
- }
-
- return bos.toByteArray();
- }
-
- public int getPartCount() {
- return this.parts == null ? 0 : this.parts.size() - 1;
- }
-
- public MimeDecoder getPart(int index) {
- if (index >= 0 && index < this.getPartCount()) {
- int i = (Integer)this.parts.elementAt(index);
- int j = (Integer)this.parts.elementAt(index + 1);
- return new MimeDecoder(this, i + 1, j);
- } else {
- throw new ArrayIndexOutOfBoundsException(index);
- }
- }
-
- public String getType() {
- return this.type;
- }
-
- public String getName() {
- return this.name;
- }
-
- public String getEncoding() {
- return this.encoding;
- }
-
- public static String getStringName(String s) {
- int p = s.indexOf(61);
- return p == -1 ? null : s.substring(0, p);
- }
-
- public static String getStringValue(String s) {
- int p = s.indexOf(61);
- String value;
- if (p == -1) {
- value = s;
- } else {
- value = s.substring(p + 1);
- }
-
- value = value.trim();
- if (value.length() > 1 && value.charAt(0) == '"' && value.charAt(value.length() - 1) == '"') {
- value = value.substring(1, value.length() - 1);
- }
-
- return value;
- }
-
- private static int decode(char c) {
- if (c >= 'A' && c <= 'Z') {
- return c - 65;
- } else if (c >= 'a' && c <= 'z') {
- return c - 97 + 26;
- } else if (c >= '0' && c <= '9') {
- return c - 48 + 26 + 26;
- } else {
- switch (c) {
- case '+':
- return 62;
- case '/':
- return 63;
- case '=':
- return 0;
- default:
- throw new RuntimeException("Illegal MIME character '" + c + "'");
- }
- }
- }
-
- private static void decode(String s, ByteArrayOutputStream bos) {
- int i = 0;
- int len = s.length();
-
- while(true) {
- while(i < len && s.charAt(i) <= ' ') {
- ++i;
- }
-
- if (i == len) {
- break;
- }
-
- int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + decode(s.charAt(i + 3));
- bos.write(tri >> 16 & 255);
- if (s.charAt(i + 2) == '=') {
- break;
- }
-
- bos.write(tri >> 8 & 255);
- if (s.charAt(i + 3) == '=') {
- break;
- }
-
- bos.write(tri & 255);
- i += 4;
- }
-
- }
- }
-